Python의 matplotlib 라이브러리로 그래프를 그릴 때 한글이 네모 박스(□□□)로 표시되는 현상이 발생한다. 이는 matplotlib의 기본 폰트가 한글을 지원하지 않기 때문이다.
matplotlib는 기본적으로 서양 문자를 지원하는 폰트를 사용하기 때문에, 한글, 중국어, 일본어 등의 문자를 표시하려면 해당 언어를 지원하는 폰트로 설정을 변경해야 한다.
matplotlib에서 한글을 정상적으로 표시하는 방법은 크게 세 가지가 있다.
코드 시작 부분에서 matplotlib.rcParams를 사용하여 폰트를 설정하는 방법이다. 가장 널리 사용되는 방법이다.
import matplotlib.pyplot as plt
# 한글 폰트 설정
plt.rcParams['font.family'] = 'Malgun Gothic' # Windows
# plt.rcParams['font.family'] = 'AppleGothic' # Mac
# plt.rcParams['font.family'] = 'NanumGothic' # Linux
# 마이너스 기호 깨짐 방지
plt.rcParams['axes.unicode_minus'] = False
시스템에 설치된 폰트를 자동으로 찾아서 설정하는 방법이다. 운영체제에 관계없이 사용 가능한 한글 폰트를 자동으로 찾아준다.
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
# 시스템에 설치된 폰트 중에서 한글 폰트 찾기
font_list = [f.name for f in fm.fontManager.ttflist]
korean_fonts = [f for f in font_list if 'Gothic' in f or 'Malgun' in f]
if korean_fonts:
plt.rcParams['font.family'] = korean_fonts[0]
print(f"사용 폰트: {korean_fonts[0]}")
else:
print("한글 폰트를 찾을 수 없습니다.")
plt.rcParams['axes.unicode_minus'] = False
시스템에 설치된 모든 폰트를 확인하려면 다음 코드를 사용한다.
import matplotlib.font_manager as fm
# 설치된 모든 폰트 출력
font_list = sorted([f.name for f in fm.fontManager.ttflist])
for font in font_list:
print(font)
ttf 파일을 직접 지정하여 사용할 수도 있다.
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
# 폰트 파일 경로 지정
font_path = 'C:/Windows/Fonts/malgun.ttf' # Windows
# font_path = '/Library/Fonts/AppleGothic.ttf' # Mac
# font_path = '/usr/share/fonts/truetype/nanum/NanumGothic.ttf' # Linux
font_prop = fm.FontProperties(fname=font_path)
plt.rcParams['font.family'] = font_prop.get_name()
plt.rcParams['axes.unicode_minus'] = False
matplotlib의 설정 파일을 직접 수정하여 모든 파이썬 코드에서 자동으로 한글 폰트가 적용되도록 하는 방법이다.
import matplotlib as mpl
# 설정 파일 위치 확인
print(mpl.matplotlib_fname())
출력된 경로의 파일을 텍스트 에디터로 열고 다음 항목을 찾아 수정한다.
# 아래 줄을 찾아서 주석(#)을 제거하고 수정
font.family : Malgun Gothic
axes.unicode_minus : False
설정을 적용하려면 matplotlib의 폰트 캐시를 삭제해야 한다.
import matplotlib.font_manager as fm
import shutil
# 폰트 캐시 삭제
cache_dir = fm.get_cachedir()
shutil.rmtree(cache_dir)
print(f"폰트 캐시 삭제 완료: {cache_dir}")
또는 수동으로 캐시 디렉토리를 찾아 삭제할 수 있다.
| 운영체제 | 캐시 디렉토리 위치 |
|---|---|
| Windows | C:\Users\사용자명\.matplotlib |
| Mac | ~/.matplotlib |
| Linux | ~/.cache/matplotlib |
각 운영체제에서 사용 가능한 대표적인 한글 폰트는 다음과 같다.
| 운영체제 | 추천 폰트 | 폰트명 (코드) |
|---|---|---|
| Windows | 맑은 고딕 | 'Malgun Gothic' |
| 굴림 | 'Gulim' |
|
| 돋움 | 'Dotum' |
|
| Mac | 애플고딕 | 'AppleGothic' |
| 나눔고딕 | 'NanumGothic' |
|
| Linux | 나눔고딕 | 'NanumGothic' |
| 본고딕 | 'Noto Sans KR' |
Linux(Ubuntu/Debian)에서 나눔폰트가 없다면 다음 명령어로 설치할 수 있다.
# 나눔고딕 폰트 설치
sudo apt-get install fonts-nanum
# 폰트 캐시 갱신
fc-cache -fv
한글 폰트를 설정한 후에는 마이너스 기호(-)가 깨져서 표시되는 문제가 발생할 수 있다. 이는 일부 한글 폰트가 유니코드 마이너스 기호를 제대로 지원하지 않기 때문이다.
# 마이너스 기호를 ASCII 문자로 사용
plt.rcParams['axes.unicode_minus'] = False
이 설정은 반드시 한글 폰트 설정과 함께 사용해야 한다.
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'Malgun Gothic' # 한글 폰트
plt.rcParams['axes.unicode_minus'] = False # 마이너스 기호
한글과 마이너스 기호가 모두 정상적으로 표시되는 완전한 그래프 예제이다.
import matplotlib.pyplot as plt
import numpy as np
# 한글 폰트 및 마이너스 기호 설정
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False
# 데이터 생성
x = np.linspace(-10, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
# 그래프 그리기
plt.figure(figsize=(10, 6))
plt.plot(x, y1, label='사인 함수', linewidth=2)
plt.plot(x, y2, label='코사인 함수', linewidth=2)
# 한글 제목 및 레이블
plt.title('삼각함수 그래프', fontsize=16, fontweight='bold')
plt.xlabel('X 축', fontsize=12)
plt.ylabel('Y 축', fontsize=12)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.show()
import matplotlib.pyplot as plt
import numpy as np
# 한글 폰트 및 마이너스 기호 설정
plt.rcParams['font.family'] = 'AppleGothic'
plt.rcParams['axes.unicode_minus'] = False
# 데이터 생성
categories = ['1월', '2월', '3월', '4월', '5월']
values = [23, 45, 56, 78, 32]
# 막대 그래프
plt.figure(figsize=(8, 5))
plt.bar(categories, values, color='skyblue', edgecolor='navy')
plt.title('월별 판매량', fontsize=14, fontweight='bold')
plt.xlabel('월', fontsize=12)
plt.ylabel('판매량 (개)', fontsize=12)
plt.grid(axis='y', alpha=0.3)
plt.show()
import matplotlib.pyplot as plt
import platform
import numpy as np
# 운영체제에 따라 폰트 자동 설정
system = platform.system()
if system == 'Windows':
plt.rcParams['font.family'] = 'Malgun Gothic'
elif system == 'Darwin': # Mac
plt.rcParams['font.family'] = 'AppleGothic'
else: # Linux
plt.rcParams['font.family'] = 'NanumGothic'
plt.rcParams['axes.unicode_minus'] = False
# 원 그래프
labels = ['Python', 'Java', 'C++', 'JavaScript', '기타']
sizes = [35, 25, 15, 15, 10]
colors = ['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#ff99cc']
plt.figure(figsize=(8, 6))
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%',
startangle=90, textprops={'fontsize': 11})
plt.title('프로그래밍 언어 사용 비율', fontsize=14, fontweight='bold')
plt.show()
Jupyter Notebook이나 JupyterLab에서는 매 노트북마다 폰트 설정을 해야 한다. 노트북 시작 부분의 첫 셀에서 설정하는 것이 좋다.
Seaborn 라이브러리를 사용하는 경우에도 동일한 방법으로 한글을 설정할 수 있다.
import seaborn as sns
import matplotlib.pyplot as plt
# 한글 폰트 설정
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False
# Seaborn 그래프
sns.set_style("whitegrid")
# 이후 그래프 작성...
자주 사용하는 설정을 함수로 만들어 재사용할 수 있다.
import matplotlib.pyplot as plt
import platform
def set_korean_font():
"""한글 폰트 자동 설정 함수"""
system = platform.system()
if system == 'Windows':
plt.rcParams['font.family'] = 'Malgun Gothic'
elif system == 'Darwin':
plt.rcParams['font.family'] = 'AppleGothic'
else:
plt.rcParams['font.family'] = 'NanumGothic'
plt.rcParams['axes.unicode_minus'] = False
print(f"한글 폰트 설정 완료: {plt.rcParams['font.family']}")
# 사용
set_korean_font()
특정 그래프 요소에만 다른 폰트를 적용할 수도 있다.
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
# 전체 설정
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False
# 특정 텍스트에만 다른 폰트 적용
font_prop = fm.FontProperties(family='Gulim', size=14)
plt.plot([1, 2, 3], [1, 4, 9])
plt.title('제목은 맑은 고딕')
plt.xlabel('X축 레이블', fontproperties=font_prop) # 굴림체 사용
plt.show()
폰트 설정이 제대로 적용되지 않는다면 다음 사항을 확인한다.
import matplotlib.pyplot as plt
# 현재 설정된 폰트 확인
print("현재 폰트:", plt.rcParams['font.family'])
print("마이너스 기호:", plt.rcParams['axes.unicode_minus'])